#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <signal.h>
#include <sys/time.h>
#include <sys/wait.h>

#include "BacInetSocket.h"

#define B_CMB_SERVER_SOCKET_ID (10086)

#define BLOGI(str, ...) do{printf("BAC_SOCKET_SERVER ");printf(str,##__VA_ARGS__);printf("\n");}while(0)
#define BLOGD(str, ...) do{printf("BAC_SOCKET_SERVER ");printf(str,##__VA_ARGS__);printf("\n");}while(0)
#define BLOGW(str, ...) do{printf("BAC_SOCKET_SERVER ");printf(str,##__VA_ARGS__);printf("\n");}while(0)
#define BLOGE(str, ...) do{printf("BAC_SOCKET_SERVER ");printf(str,##__VA_ARGS__);printf("\n");}while(0)

using namespace com::fiill;

BacInetSocketServer * server {NULL};

int call_popen(const char * str, char* const outData, int maxBuffSize) {
    FILE *fp;
    int ret = -1, len = 0;

    BLOGD("call popen() >>> %s", str);
    fp = popen(str, "r");
    if(NULL == fp) {
        BLOGE("call popen() fp is null!");
        return -1;
    }
    while(fgets(outData + len, maxBuffSize - len, fp) != NULL) {
        len = strlen(outData);
    }
    if(len > 0) ret = 0;
    //BLOGE("call popen() outData=%s", outData);
    pclose(fp);
    return ret;
}

int call_system(const char * str, char* const outData, int maxBuffSize) {
    pid_t status;
    int ret = 0;

    BLOGD("FD:%d, process command >>> %s", outData[0], str);
    outData[0] = 0;

    //TODO check str
    if(maxBuffSize > 0) {
        status = system(str);
        if (-1 == status) {
            //BLOGD("system() error <<< %d", status);
            ret = status;
        } else {
            //BLOGD("system() exit value=[0x%x]", status);
            ret = WEXITSTATUS(status);
            if (0 != ret){
                BLOGD("run script fail, script exit code: %d", ret);
            }
        }
    }
    return ret;
}

int sh(const char * str, char* const outData, int maxBuffSize) {

    BLOGD("FD:%d, process command >>> %s", outData[0], str);
    outData[0] = 0;

    if(str == strstr(str, "popen ")) {
        return call_popen(str + strlen("popen "), outData, maxBuffSize);
    } else if(str == strstr(str, "system ")) {
        return call_system(str, outData, maxBuffSize);
    } else {
        BLOGW("%s", str);
	return 0;
    }
}

static void startSocketServer(const int port) {
    server = (BacInetSocketServer*)new BacInetSocketServer(port, sh, 0);
    if (server->service_listen() < 0) {
        BLOGE("service listen() failed");
    }
    server->start_process();
}

int main(int argc, char * argv[]) {
    int port = B_CMB_SERVER_SOCKET_ID;
    if (argc >= 2) {
        port =  atoi(argv[1]);
    }

    if(port > 1000) {
        startSocketServer(port);
    }
    BLOGD("exit. port=%d", port);
    return 0;
}

